#include "serialportmanager.h"

QAtomicPointer<SerialPortManager> SerialPortManager::m_instance(nullptr);
QMutex SerialPortManager::m_mutex;

SerialPortManager* SerialPortManager::instance()
{
    // 双重检查锁定保证线程安全
    if(m_instance.loadAcquire() == nullptr) {
        QMutexLocker locker(&m_mutex);
        if(m_instance.loadAcquire() == nullptr) {
            SerialPortManager* temp = new SerialPortManager();
            QThread* workerThread = new QThread();

            // 将对象移动到新线程
            temp->moveToThread(workerThread);

            // 连接线程启动信号与初始化槽
            QObject::connect(workerThread, &QThread::started,
                             temp, &SerialPortManager::init);

            // 跨线程信号槽连接
            QObject::connect(temp, &SerialPortManager::openPortRequested,
                             temp, &SerialPortManager::handleOpenPort,
                             Qt::QueuedConnection);

            QObject::connect(temp, &SerialPortManager::closePortRequested,
                             temp, &SerialPortManager::handleClosePort,
                             Qt::QueuedConnection);

            QObject::connect(temp, &SerialPortManager::writeDataRequested,
                             temp, &SerialPortManager::handleWriteData,
                             Qt::QueuedConnection);

            workerThread->start();
            m_instance.storeRelease(temp);
        }
    }
    return m_instance.loadAcquire();
}

SerialPortManager::SerialPortManager(QObject *parent)
    : QObject(parent), m_serial(nullptr)
{
}

SerialPortManager::~SerialPortManager()
{
    // 清理串口资源
    if (m_serial) {
        if (m_serial->isOpen()) {
            m_serial->close();
        }
        delete m_serial;
        m_serial = nullptr;
    }

    // 停止并清理线程
    QThread* currentThread = this->thread();
    if (currentThread && currentThread->isRunning()) {
        currentThread->quit();
        currentThread->wait(500);
        delete currentThread;
    }
}

void SerialPortManager::init()
{
    // 在专用线程中创建串口对象
    m_serial = new QSerialPort(this);
    connect(m_serial, &QSerialPort::readyRead,
            this, &SerialPortManager::handleReadyRead);
}

void SerialPortManager::openPort(const QString &portName, qint32 baudRate)
{
    emit openPortRequested(portName, baudRate);
}

void SerialPortManager::closePort()
{
    emit closePortRequested();
}

void SerialPortManager::writeData(const QByteArray &data)
{
    emit writeDataRequested(data);
}

bool SerialPortManager::isOpen() const
{
    // 确保线程安全（可选：根据实际需求添加互斥锁）
    return m_serial && m_serial->isOpen();
}

void SerialPortManager::handleOpenPort(const QString &portName, qint32 baudRate)
{
    if (m_serial->isOpen()) {
        m_serial->close();
    }

    m_serial->setPortName(portName);
    m_serial->setBaudRate(baudRate);
    m_serial->setDataBits(QSerialPort::Data8);
    m_serial->setParity(QSerialPort::NoParity);
    m_serial->setStopBits(QSerialPort::OneStop);
    m_serial->setFlowControl(QSerialPort::NoFlowControl);

    bool success = m_serial->open(QIODevice::ReadWrite);
    emit portOpened(success);

    if(success) {
        qDebug() << "Port opened:" << portName;
    } else {
        qWarning() << "Open failed:" << m_serial->errorString();
    }
}

void SerialPortManager::handleClosePort()
{
    if (m_serial->isOpen()) {
        m_serial->close();
        emit portOpened(false);
        qDebug() << "Port closed";
    }
}

void SerialPortManager::handleWriteData(const QByteArray &data)
{
    if (m_serial && m_serial->isOpen()) {
        qint64 bytesWritten = m_serial->write(data);
        if(bytesWritten == -1) {
            qWarning() << "Write error:" << m_serial->errorString();
        } else if(bytesWritten != data.size()) {
            qWarning() << "Data partially written, expected:"
                       << data.size() << "actual:" << bytesWritten;
        }
    }
}

void SerialPortManager::handleReadyRead()
{
    const QByteArray data = m_serial->readAll();
    if (!data.isEmpty()) {
        emit dataReceived(data);
        qDebug() << "Received data:" << data.toHex(' ');
    }
}
